/*
 * Created on Apr 11, 2006
 */
package com.mgmaps.gps;

import com.nutiteq.components.WgsPoint;

/**
 * Generic thread that deals with GPS receiving
 *
 * @author CristiS
 * @version 1.0
 */
public abstract class GPSReceiver extends Thread {

  protected boolean active;
  protected boolean started;
  protected boolean quitting;
  
  protected boolean hasFix;
  protected long fixTime;
  protected long clockDelta;
  protected boolean currentFix;
  
  /**
   * Constructor for GPSReceiver.
   */
  public GPSReceiver() {
    started = false;
    quitting = false;
    hasFix = false;
    currentFix = false;
  }
  
  /**
   * Activate this receiver.
   */
  public synchronized void activate() {
    active = true;
    if (!started)
      start();
    notify();
  }
  
  /**
   * Deactivate this receiver.
   */
  public synchronized void deactivate() {
    active = false;
    if (isConnected())
      disconnect();
    else
      notify();
  }

  /**
   * Whether a fix was obtained.
   *
   * @return Returns the value of hasFix.
   */
  public boolean getHasFix() {
    return hasFix;
  }

  /**
   * Whether the fix is current.
   * 
   * @return Returns the value of currentFix.
   */
  public boolean getCurrentFix() {
    return currentFix;
  }
  
  /**
   * Last fix time.
   * 
   * @return the last fix time
   */
  public long getFixTime() {
    return fixTime;
  }
  
  /**
   * Difference between GPS clock and system clock.
   * @return long
   */
  public long getClockDelta() {
    return clockDelta;
  }
  
  /**
   * Get fix time adjusted for local phone time.
   * @return fix time adjusted by clock delta.
   */
  public long getFixTimeAdjusted() {
    return fixTime+clockDelta;
  }

  /**
   * Get the current location, altitude, speed, heading, precision.
   */
  public abstract WgsPoint getPoint();
  public abstract double getAltitude(); // m
  public abstract double getSpeed(); // km/h
  public abstract double getHeading(); // degrees
  public abstract double getPrecision(); // m
  
  /**
   * Get satellite info.
   */
  public abstract int[] getFixSatellites();
  public abstract SatelliteData[] getSatelliteData();
  
  /**
   * Check if the GPS is connected.
   * @return true if connected, false otherwise
   */
  public abstract boolean isConnected();
  
  /**
   * Check if a connection to the GPS was attempted and failed.
   * @return true if the GPS is not connected and a connection was attempted
   */
  public abstract boolean connectError();
  
  /**
   * Disconnect from the GPS device.
   */
  protected abstract void disconnect();
  
  /**
   * Synchronized getter for quitting.
   * @return the value of quitting
   */
  public synchronized boolean isQuitting() {
    return quitting;
  }
  
  /**
   * Set quitting to true in a synchronized manner.
   * 
   * @see com.mgmaps.gps.GPSReceiver#notifyExit()
   */
  public synchronized void notifyExit() {
    quitting = true;
    deactivate();
  }
  
  /**
   * Synchronized getter for started.
   *
   * @return the value of started
   */
  public synchronized boolean isStarted() {
    return started;
  }
}
